/*
程序架构: 一共11个c文件(不含外部芯片驱动)，四层
主控层：APP: 主APP - akm_9xx.c, 辅助/全局 - akm_gl.c
业务层：任务: 温控器模块-task_ctrl.c, 数据(温度)采集模块-task_gather.c, 控制台模块-task_console.c, IOT模块(含OTA)-task_iot.c, debug辅助-task_dbg.c
HAL层: 键盘/显示-hal_disp_key.c, ADC-hal_adc.c, UART-hal_uart.c, 其他各种GPIO控制/10ms主定时器/nv - hal_mcu.c
Driver层: TM1618显示驱动-drv_tm1618.c, PT6964显示驱动-drv_disp_key_pt6964.c, MCU_IO自身显示驱动-drv_disp_key_mcu582.c, PC模拟器显示驱动 - drv_disp_key_emu.c
*/

#include "CH58x_common.h"
#include "CH58xBLE_LIB.H"
#include "zqm_global.h"
#include "zqm_module.h"
#include "zqm_app.h"
#include "hal_mcu.h"
#include "hal_disp_key.h"

#include "task_iot.h"
#include "task_console.h"
#include "task_gather.h"
#include "task_ctrl.h"
#include "hal_adc.h"
#include "hal_uart.h"
#include "task_dbg.h"
#include "task_ble.h"
#include "task_c485.h"

// ##全局变量 ------------------------------------------------------------------------------------
char cat1_sw_ver[ZQ_VER_MAX_LEN] = { 0 };	// 接收cat1版本号, 类似"1.0.2.00"

M0DiagnosticInfo m0_diag = {                        // 系统基础和自检信息
    {0xAB, 0x81, 0x90, 0xD5, 0xD1, 0x1E, 0x49, 0x41, 0xAC, 0xC4, 0x42, 0xF3, 0x05, 0x10, 0xB4, 0x08},
    {0x27, 0x73},
    {0x00, 0x00},
    {0x11, 0x22, 0x33, 0x44, 0x55, 0x66},
    0,0,0,
    0,
    START_CAUSE_M_POWUP,
    START_CAUSE_C_POWUP,
    0
};                           

// 休眠激活后, IOT指示任务完成，可以被关闭
int IsCat1ReadyOff = 0;

// 冷热型切换专用 Start----------------------------------------------------------------------------------------
void ZySwitchCtrlMode(void)
{
    //TODO 下面的代码需要修正
    //if (zy_funcs.tem_ctrl == (CTRL_MODE_COOL | CTRL_MODE_HOT)) {// 冷热型
    //    // 关闭所有强电控制, 比如制冷-制热, 切换过去后，制冷逻辑不跑, 压机没机会关闭了
    //    MotoSwitch(0);
    //    HeaterSwitch(0);
    //    FanSwitch(0);
    //    if (zy_st.ctrl_mode & CTRL_MODE_COOL) {
    //        zqm_cfg.ctrl_mode = CTRL_MODE_HOT;
    //        memcpy(pm_val, pmh_def, PM_NUM * sizeof(short));
    //    }
    //    else {
    //        zqm_cfg.ctrl_mode = CTRL_MODE_COOL;
    //        memcpy(pm_val, pmc_def, PM_NUM * sizeof(short));
    //    }
    //    PmSave();
    //}
}
// 冷热型切换专用 End ----------------------------------------------------------------------------------------

// 检测12v是否恢复, 没有立刻返回, 检测到电源，会继续检测1s，才判定成功, 所以会最多阻塞1s
static int IsPowResume(void)
{
    // 检测12v是否恢复, 连续0.8s检测到，判定成功
    for (int i = 0; PowRead12vState(); i++, DelayMs(200)) {
        if (i >= 4)
            return 1;
    }
    return 0;
}
// 处理消息循环, TASK_PERIOD 周期调用
static void ZyDoMessage(void)
{
    int i = 0;
    ZqMessage msg;
    msg.id = 0;
    if(zy_st.ctrl_state == CTRL_STATE_DIAG_1004) { // 控制器温度测试模式，不处理按键
        ConsoleTaskDiag(&msg); // 保证DiagConsoleTask每50ms调用一次
        return;
    }

    TaskConsole(&msg); // 保证ConsoleTask每50ms调用一次
    for (; i < ZQ_KEY_NUM; i++) { //一个周期最多处理ZQ_KEY_NUM条消息, 防止多键同时动作
        ZqGetMessage(&msg);
        if (msg.id == 0)
            break;
        else if ((msg.id & ZY_EVENT_KEY) != 0)
            TaskConsole(&msg);
    }
}

// copy from ftm.h, FTM data structure, save in FTM_DEV_INFO_FLASH_ADDR.
typedef struct {
  int32_t  bootmode; // 01:SA, 02:FA, 03:WK
  uint8_t  sn[32];
  uint8_t  sn_len;
  uint8_t  did[32];
  uint8_t  did_len;
  /* M0也有机会要保存这3个值的 */
  uint8_t  ble_uuid[16];
  uint16_t ble_major;
  uint16_t ble_minor;
  uint32_t flag;

  int8_t vol_radio_delta;
  int8_t cur_radio_delta;
  int8_t pow_radio_delta;
} FTMDevInfo;
void ZyLoadFtmData(void)
{
    FTMDevInfo ftm = {0};
   	EEPROM_READ(FTM_DEV_INFO_FLASH_ADDR, (uint8_t*)&ftm, sizeof(FTMDevInfo));
    m0_diag.run_in_ftm = (ftm.bootmode == 1 || ftm.bootmode == 2) ? 1 : 0;

    if(ftm.ble_major != 0 && ftm.ble_major != 0xffff) {   // 判断文件中蓝牙参数有效性
        memcpy(m0_diag.ble_uuid, ftm.ble_uuid, sizeof(m0_diag.ble_uuid));
        m0_diag.ble_major[0] = (uint8_t)((ftm.ble_major & 0xff00) >> 8);
        m0_diag.ble_major[1] = (uint8_t)(ftm.ble_major & 0x00ff);
        m0_diag.ble_minor[0] = (uint8_t)((ftm.ble_minor & 0xff00) >> 8);
        m0_diag.ble_minor[1] = (uint8_t)(ftm.ble_minor & 0x00ff);
    }
    if(ftm.cur_radio_delta != 0 && ftm.cur_radio_delta > -100 && ftm.cur_radio_delta < 100) {   // 判断文件中功率计矫正系数有效性
        m0_diag.ftm_vol_delta = ftm.vol_radio_delta;
        m0_diag.ftm_cur_delta = ftm.cur_radio_delta;
        m0_diag.ftm_pow_delta = ftm.pow_radio_delta;
    }
}

// 初始化全局量
static void ZqInitVariables(void)
{
    IsCat1ReadyOff = 0;
    // init message queue
    ZqInitMsgQueue();
    // 加载相应的系统参数集
    if(zqm_cfg.ctrl_mode & CTRL_MODE_COOL) zqm_cfg.ctrl_mode = CTRL_MODE_COOL; // 多模式(热/冷藏/冷冻)柜子出厂强制冷模式cool模式
    zy_st.ctrl_switch = CTRL_ALL_SWITCH; // 预先初始化开关量为全开
    PmLoad();
    // 初始化系统状态
    int comp_off_timer = zy_st.comp_off_timer; 
    memset(&zy_st, 0, sizeof(zy_st));   // init state table
    zy_st.comp_off_timer = comp_off_timer;  // 压机延时不清零
    // zy_st.ctrl_switch = CTRL_REMOTE_SWITCH | CTRL_HARD_SWITCH | (zqm_cfg.ctrl_switch << 2);   // 初始化开关量: remote=1,hard=1,soft=localswitch
#if(CFG_DEVICE_TYPE == 760)
    zy_st.ctrl_switch = (zqm_cfg.ctrl_switch & (CTRL_SOFT_SWITCH | CTRL_REMOTE_SWITCH)) | CTRL_HARD_SWITCH;   // 加载开关量, 记忆soft switch和remote switch
#else
    zy_st.ctrl_switch = (zqm_cfg.ctrl_switch & CTRL_SOFT_SWITCH) | (CTRL_HARD_SWITCH | CTRL_REMOTE_SWITCH);   // 加载开关量, 之记忆soft switch
#endif

    zy_st.ctrl_mode = zqm_cfg.ctrl_mode;
    zy_st.ctrl_state = CTRL_STATE_NORMAL;
    zy_st.vbat = NUM_INVALID_WORD;
    // initial adc
    AdcResetRef();
    AdcResetNtc1();
    AdcResetNtc2();
    AdcResetVBat();
    // initial display temperature
    last_disp_tem = 0;
    // init ble mac addr
    GetMACAddress(&(m0_diag.ble_mac));
    ZQLOG("Get 582M Ble Mac addr: %02X:%02X:%02X:%02X:%02X:%02X", m0_diag.ble_mac[5], m0_diag.ble_mac[4], m0_diag.ble_mac[3], m0_diag.ble_mac[2], m0_diag.ble_mac[1], m0_diag.ble_mac[0]);
}
// 部分初始化全局变量, wifi/BT/4g/Batter 四个灯状态保持。
static void ZqInitVariablesPartially(void)
{
    uint8_t wifi = zy_st.wifi;
    uint8_t ble = zy_st.ble;
    uint8_t _4g = zy_st._4g;
    short vbat = zy_st.vbat;
    int defrost_timer = 0;
    if (CFG_DEVICE_TYPE == 1004 || CFG_DEVICE_TYPE == 1026) {// 1004系列机型要求 d3化霜周期不清零
        if (!(zy_st.comp_mode & COMP_MODE_DEFROST_MASK)) // 非化霜期间软重启, 
            defrost_timer = zy_st.defrost_timer;
    }
    ZqInitVariables();
    zy_st.wifi = wifi;      // 恢复后保持这些灯状态。
    zy_st.ble = ble;
    zy_st._4g = _4g;
    zy_st.vbat = vbat;
    zy_st.defrost_timer = defrost_timer;
}

//掉电上报状态
static int CtrlRunPrePowOff(void)
{
    zy_st.ctrl_state = CTRL_STATE_LP_PRE;       // 设置运行状态
    ZQLOG("App starting...ver = %s, ctrl state = power off pre-", ZQ_SW_VER_STR);
    DispAllItems(0);                            // 关显示
    zy_st.comp_on_timer = 0;                    // 关闭所有强电控制, 不然上电（12v）或导致继电器开启。
    zy_st.comp_state = zy_st.fan_state = 0;      
    GPIO_ResetBits(zy_ios.motor); 
    GPIO_ResetBits(zy_ios.fan);
    GPIO_ResetBits(zy_ios.condenser_fan);
    GPIO_ResetBits(zy_ios.heater);
    GPIO_ResetBits(zy_ios.light);
    GPIO_ResetBits(zy_ios.melt);
    for(int timer_ms = 0; ;timer_ms += TASK_PERIOD) {              // main loop
        WdtClean();
        if (IsPowResume())                  // 侦测到市电恢复, 返回正常模式
            return CTRL_STATE_NORMAL;
        TgTask_LP();            // 低功耗数据采集, 
        TiTask();               // IOT处理
        if (timer_ms > 2* 60 * 1000)        // 2分钟超时, 进低功耗
        {
            ZQLOG("low power upload overtime, sleep...");
            break;
        }
        if (IsCat1ReadyOff && timer_ms > 2000) // 接收到cat1完成通知, 关闭cat1, 切换回低功耗模式, 最小保持2s, 用来跳出循环后检测RTC是否有效(防止睡死)
        {
            ZQLOG("low power upload success, sleep...");
            break;
        }

        zy_wait_for_next_loop();
    }
    Cat1PowerOff();
    zy_wait_for_next_loop();                // 等待一些操作，比如debug信息同步等
    return CTRL_STATE_LP; // 切换回低功耗模式
}
//低功耗24H上报状态: 恢复MCU正常配置 - 开cat1 - cmd01响应 - 收到cmd80关cat1) - 恢复休眠配置
static int CtrlRunLP24H(void)
{
    zy_st.ctrl_state = CTRL_STATE_LP_24H;   // 设置运行状态
    GPIOInit_Normal();                      // 配置GPIO, 关cat1
    DbgTaskInit();                          // 调试串口初始化
    ZQLOG("App starting...ver = %s; ctrl state = low power 24H upload", ZQ_SW_VER_STR);
    ZqInitVariables();                      // 初始化全局量
    BatteryInit();                          // 电池初始化
    Cat1PowerOn(START_CAUSE_C_24H);         // 启动cat1

    uint32_t timer_s = zq_timer_rtc_s;      // 记录开始时间
    M0TimerClear();     // clear timer
    while (1) {                             // main loop
        WdtClean();
        if (IsPowResume())                  // 侦测到市电恢复, 返回正常模式
            return CTRL_STATE_NORMAL;
        TgTask_LP();            // 低功耗数据采集, 
        TiTask();               // IOT处理
        if (zq_timer_50ms > 2* 60 * 1000)        // 2分钟超时, 进低功耗
        {
            ZQLOG("low power 24H upload overtime, sleep...");
            break;
        }
        if (IsCat1ReadyOff && zq_timer_50ms > 2000) // 接收到cat1完成通知, 关闭cat1, 切换回低功耗模式, 最小保持2s, 用来跳出循环后检测RTC是否有效(防止睡死)
        {
            ZQLOG("low power 24H upload success, sleep...");
            break;
        }
        zy_wait_for_next_loop();
    }
    Cat1PowerOff();
    zy_wait_for_next_loop();                // 等待一些操作，比如debug信息同步等
    IsCat1ReadyOff = 0;
    if (zq_timer_rtc_s > timer_s)           // 检查RTC是否还在运行，防止睡死
        return CTRL_STATE_LP;               // 切换回低功耗模式
    else    // RTC死了, reset
        SYS_ResetExecute();
    return CTRL_STATE_NORMAL;               // 不会走到这个位置
}
// 低功耗工作状态: 侦测电源电池状态 - 判断24H - 休眠1s  ---- 循环
int CtrlRunLP(void)
{
    zy_st.ctrl_state = CTRL_STATE_LP;   // 设置运行状态
    GPIOInit_Sleep();                   // 配置低功耗GPIO

    // 增加电源侦测中断，使能电源唤醒，没有具体处理事务，目的是小概率睡眠RTC唤醒失效时，增加上电唤醒保护
    uint32_t irq;
    SYS_DisableAllIrq(&irq);    // 要关中断操作，否则GPIO_ITModeCfg(IO_DET_12V, GPIO_ITMode_RiseEdge);似乎会引发死机
    GPIO_ModeCfg(zy_ios.det_12v, GPIO_ModeIN_PU);
    GPIO_ITModeCfg(zy_ios.det_12v, GPIO_ITMode_RiseEdge);          // 上升沿触发
    SYS_RecoverIrq(irq);
    ((zy_ios.det_12v & ZyGPIO_MASK) == zy_ios.det_12v) ? PFIC_EnableIRQ(GPIO_A_IRQn) : PFIC_EnableIRQ(GPIO_B_IRQn);
    ((zy_ios.batt_chrg & ZyGPIO_MASK) == zy_ios.batt_chrg) ? (R16_PA_INT_EN &= (~zy_ios.batt_chrg)) : (R16_PB_INT_EN &= (~(zy_ios.batt_chrg & ZyGPIO_MASK))); // 关闭电池侦测中断等其他中断唤醒源
    ((zy_ios.det_human & ZyGPIO_MASK) == zy_ios.det_human) ? (R16_PA_INT_EN &= (~zy_ios.det_human)) : (R16_PB_INT_EN &= (~(zy_ios.det_human & ZyGPIO_MASK)));
    PWR_PeriphWakeUpCfg(ENABLE, RB_SLP_GPIO_WAKE, Long_Delay);  // 使能GPIO唤醒
    for (uint32_t start = zq_timer_rtc_s; ;) {
        WdtClean();
        if (IsPowResume())  // 侦测到市电恢复, 返回正常模式
            return CTRL_STATE_NORMAL;
        if(zy_st.vbat > 3480) {// 电池电量够
            uint32_t span = zq_timer_rtc_s - start;
            if (span > (24*60*60))  // 检查到24小时到, 开启IOT上报,
                return CTRL_STATE_LP_24H;
            if ((span % (60 * 60) == 0))  // 增加每小时校准内部低频时钟一次
                Calibration_LSI(Level_64);  // 校准RTC 用时 2.2ms 800ppm  (32M 主频)  1000ppm (60M 主频)
        }
        McuSleep();     // 休眠1s
   }
}
// 正常工作状态
static int CtrlRunNormal(void)
{
    zy_st.ctrl_state = CTRL_STATE_NORMAL;
    GPIOInit_Normal();                      // 配置GPIO, 关cat1
    DbgTaskInit();                          // 调试串口初始化
    ZQLOG("App starting...ver = %s, cause = %d; ctrl state = normal", ZQ_SW_VER_STR, m0_diag.m0_start_cause);
    ZqInitVariables();                      // 初始化全局量
    BatteryInit();                          // 电池初始化
    Cat1PowerOn(START_CAUSE_C_POWUP);       // 启动cat1
    DispKeyInit();                          // 显示面板初始化, 模拟开机自检显示
    ZyLoadFtmData();                        // load ftm data

#if (!ZQ_SIMULATOR)
    // [panzhimin] ftm start
    extern void ftm_start(void);
    ftm_start();
    // [panzhimin] ftm end
#endif
    BleExchInit(0);                          // 蓝牙初始化

    zq_timer_rtc_s_pow = 0;                         // 初次上电或者休眠唤醒开始计时
CtrlRunNormal_CTRL_STATE_RESET_SELF:
    if (zy_st.ctrl_state == CTRL_STATE_RESET_SELF) {// soft reset
        zy_st.ctrl_state = CTRL_STATE_NORMAL;       // 恢复运行状态
        ZqInitVariablesPartially();                 // 初始化全局量
        //last_disp_tem = ZY_TEM_INVALID;             // 恢复后直接显示目标温度。
    }
    else if (zy_st.ctrl_state == CTRL_STATE_MODE_SWITCH) { // mode switch
        ZySwitchCtrlMode();
        zy_st.ctrl_state = CTRL_STATE_NORMAL;            // 恢复运行状态
        ZqInitVariablesPartially();  // 初始化全局量
        //last_disp_tem = ZY_TEM_INVALID;             // 恢复后直接显示目标温度。
    }

    M0TimerClear();     // clear timer
    for(uint32_t last_s = 0; ;WdtClean()) {       // main loop
        int span_1s = zq_timer_s - last_s;
        last_s = m0_diag.m0_run_time = zq_timer_s;
        // cat1 心跳控制
        Cat1HeartbeatMonitor();
        // 如果没有市电供电, 进入低功耗
        if (!PowRead12vState()) {   
            return CtrlRunPrePowOff();
        }
        // 数据采集        
        TgTask(span_1s);    
        TMOS_SystemProcess();
        // 通讯协议处理
#if (ZQ_COMM_PLATFORM == 8850 || ZQ_COMM_PLATFORM == 8910)
        TiTask();               // IOT处理
#elif (ZQ_COMM_PLATFORM == 485)
        C485Task();             // 485处理
#endif
        TMOS_SystemProcess();
        // 控制器界面处理
        KeyScan();              // 键盘扫描
        ZyDoMessage();          // 键盘消息处理
        TMOS_SystemProcess();
        // 控制器动作
        if(zy_st.ctrl_state == CTRL_STATE_DIAG_1004)  // 控制器温度测试模式
            Task_DiagTempCtrl(span_1s, false); 
        else
            Task_TempCtrl(span_1s); 
        if (zy_st.ctrl_state == CTRL_STATE_RESET_SELF || zy_st.ctrl_state == CTRL_STATE_MODE_SWITCH) { // 关机或者sw reset 或者 switch cool/hot mode 
            ZQLOG(">>>>>>>>>> Controllor will reset with mode: %d", zy_st.ctrl_state);
            goto CtrlRunNormal_CTRL_STATE_RESET_SELF;
        }
        else if (zy_st.ctrl_state == CTRL_STATE_RESET_HD) // hardware level reset
            DelayMs(2000);  // whatchdog overtime and reset
        TMOS_SystemProcess();
        // 显示刷新
        DispRefresh();
        // 主循环时间间隔控制
        zy_wait_for_next_loop();
    }
    return CTRL_STATE_NORMAL; // 不应该出现这种case
}

//int main(int argc, char** argv)
int zy_main()
{
    SetSysClock(CLK_SOURCE_PLL_60MHz);      // 设定运行频率
    WWDG_ResetCfg(ENABLE);                  // 开狗, 60M Fsys下 固定131072/Fsys * 256大概500ms reset。保持全局开狗，最大覆盖程序生命周期，休眠也不会关闭(休眠狗依赖的高频时钟停跑，所以不会超时)       
    Calibration_LSI(Level_128);             // 校准RTC
    RtcInit_1s();                           // 启动1s RTC定时
    m0_diag.m0_start_cause = (R8_RESET_STATUS & 0x07);  // 记录启动原因
    zy_st.comp_off_timer = 1000 * 60;          // 压机延迟保护初始化, 刚上电, 没有记忆值, 只能预设极大值

    int ret = CTRL_STATE_NORMAL;
controller_reset:
    M0InitTimer();                           // 启动主任务定时器和tick计数器
    if (ret == CTRL_STATE_LP) // 低功耗模式
        ret = CtrlRunLP();
    else if(ret == CTRL_STATE_LP_24H)
        ret = CtrlRunLP24H();
    else
        ret = CtrlRunNormal();
    DelayMs(50); 
    goto controller_reset;
}

// -------------------------------------------------------------------------------------------------
#ifdef ZQ_SIMULATOR
#include <Windows.h>
#include <process.h>
#include <time.h>
#include "simu_mcu582.h"
void zy_wait_for_next_loop(void)
{
    static unsigned long long loop_start_time_ms = 0;   // 循环开始时间
    if(zq_timer_50ms == 0)
        loop_start_time_ms = 0;
    // 在这个窗口期间, 可以用来等待模拟器交换数据。
    ReleaseMutex(simu_mutex);
    DbgTask();
    WaitForSingleObject(simu_mutex, -1);
    for (int i = 0; zq_timer_50ms == loop_start_time_ms; i++) {
        Sleep(5);
    }
    loop_start_time_ms = zq_timer_50ms;
}
#else
void zy_wait_for_next_loop(void)
{
    static uint32_t loop_start_time_ms = 0;   // 循环开始时间
    if(zq_timer_50ms == 0)
        loop_start_time_ms = 0;
    // 在这个窗口期间, 可以用来等待模拟器交换数据。
    DbgTask();
    if(zq_timer_50ms == loop_start_time_ms && zq_timer_50ms % 10000 == 0) {// 任务循环有多余时间, 并且10s间隔，打印一次debug信息
        short mv1 = AdcGetNtc1(); 
        short mv2 = AdcGetNtc2(); 
        short ref = AdcGetRef(); 
        int om = ADC_OM_BASE_DEF * mv1 / (ref - mv1);
        short vbat = AdcGetVBat();
        int _12v = PowRead12vState();
        ZQLOG("zq_timer_rtc_s = %u, adc_mv1:%d, adc_mv2:%d, adc_vbat:%d, adc_ref:%d, om:%d, m_temp:%d, vbat:%d, 12V:%d, ctrl_switch:%d, door_time:%d, human:%d", 
            zq_timer_rtc_s, mv1, mv2, vbat, ref, om, zy_st.m_temp, zy_st.vbat, _12v, zy_st.ctrl_switch, zy_st.door1_timer, zy_st.humman);
    }
    for (int i = 0; zq_timer_50ms == loop_start_time_ms; i++, TMOS_SystemProcess());
    loop_start_time_ms = zq_timer_50ms;
}
#endif

// test codes -------------------------------------------------------------------------------------------------
// void TestDispPannel(void)
// {
//     static int state = -1;
//     M0TimerClear();     // clear timer

//     for(uint32_t last_s = 0; ;WdtClean()) {       // main loop
//         int span_1s = zq_timer_s - last_s;
//         last_s = m0_diag.m0_run_time = zq_timer_s;

//         KeyScan();
//         if (KeyGetState(ZQ_KEY_SET) == ZQ_EVENT_KEY_DOWN)
//             ZQLOG("key down = ZQ_KEY_SET");
//         //else if (KeyGetState(ZQ_KEY_PLUS) == ZQ_EVENT_KEY_DOWN)
//         //    ZQLOG("key down = ZQ_KEY_PLUS");
//         //else if (KeyGetState(ZQ_KEY_MINUS) == ZQ_EVENT_KEY_DOWN)
//         //    ZQLOG("key down = ZQ_KEY_MINUS");
        
//         if(zq_timer_50ms % 5000 == 0){
//             if(state >= LED_ICON_NUM) {
//                 state = -1;
//                 DispAllItems(0);
//             }
//             else{
//                 extern const uint8_t led_icon_code_table[LED_ICON_NUM][2];
//                 for (state += 1; (state < LED_ICON_NUM) && (led_icon_code_table[state][1] == 0); state++); // 跳过无效的图标
//             }
//             ZQLOG("**********: %d", zq_timer_50ms);
//         }

//         if (state >= 0) {
//             if (state < LED_ICON_NUM)
//                 DispIcon(state, disp_mode_on);
//             else
//                 DispAsFloat(-123, disp_mode_on);
//         }

//        // 显示刷新
//         DispRefresh();
//         // 主循环时间间隔控制
//         zy_wait_for_next_loop();
//     }
// }

